<template>
  <div class="center">
    <sninfo-details :online="is_online" :studentStatus="studentStatus" :snData="sn" v-if="detailsShow" @sninfoClose="sninfoClose" @initWebSocket="initWebSocket"></sninfo-details>
    <div v-else>
      <div class="header_search " v-if="searchShow">
        <el-form size="mini">
          <div class="flex flex-wrap">
            <el-form-item label="SN码" class="searchI" label-width="120px">
              <el-input size="mini" v-model="listQuery.sn" placeholder="请输入SN码"></el-input>
            </el-form-item>
            <el-form-item label="归属" class="searchI" label-width="120px">
              <el-select v-model="listQuery.username" placeholder="请选择归属" size="mini" style="width:163px" filterable @change="infoChange">
                <el-option v-for="(item,index) in snParams" :key="index" :label="`${item.username} - ${item.title}
              ${item.a_username != null ? '('+ item.a_username + '-' + item.a_title +')' : ''}`" :value="item.username"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="批次" class="searchI" label-width="120px">
              <el-select v-model="listQuery.bId" placeholder="请选择批次" size="mini" style="width:163px">
                <el-option v-for="(item,index1) in batchArray" :key="index1" :label="item.batch" :value="item.id"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="在线状态" class="searchI" label-width="120px">
              <el-select v-model="listQuery.is_online" placeholder="请选择在线状态" style="width:163px">
                <el-option label="在线" value="1"></el-option>
                <el-option label="离线" value="2"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item class="searchI" label-width="120px">
              <div class="flex felx_align">
                <el-button size="mini" type="primary" @click="getquerySn()">提交</el-button>
                <el-button size="mini" @click="restParams">重置</el-button>
              </div>
            </el-form-item>
          </div>
        </el-form>
      </div>
      <!-- 头部 -->
      <div class="table_searchs flex flex_bet flex-wrap">
        <div class="table_button flex felx_align">
          <el-button type="primary" icon="el-icon-refresh" size="mini" @click="Refresh"></el-button>
          <el-button type="primary" icon="el-icon-plus" size="mini" @click="getdeviceGetParam">设备转交</el-button>
          <el-button type="primary" icon="el-icon-delete-solid" size="mini" @click="equipment">设备回收</el-button>
          <el-button type="primary" icon="el-icon-upload2" size="mini" @click="exporFormVisible = true">导出设备归属</el-button>
          <el-button type="primary" size="mini" @click="handleDownload">
            SN码归属导入模板
            <i class="el-icon-paperclip el-icon--right"></i>
          </el-button>
          <div class="guidetext" @click="imgShow = true"><i class="iconfont iconiconfontwenhao1 guide"></i>操作指引</div>
        </div>
        <div class="table_searchs flex felx_align">
          <div class="table_search flex">
            <el-input placeholder="搜索" v-model="searchTable" class="input-with-select" size="small">
              <el-select v-model="select" slot="prepend" placeholder="请选择" class="table_select" style="width:105px">
                <el-option label="sn码" value="sn"></el-option>
                <el-option label="归属" value="username"></el-option>
                <!-- <el-option label="批次" value="3"></el-option> -->
                <!-- <el-option label="系统固件版本号" value="4"></el-option>
              <el-option label="设备信息版本号" value="5"></el-option>
              <el-option label="教官壹版本号" value="6"></el-option>
              <el-option label="在线状态" value="7"></el-option> -->
              </el-select>
              <el-button slot="append" icon="el-icon-search" @click="idnameSearch"></el-button>
            </el-input>
          </div>
          <el-button size="mini" type="primary" style="margin:0 8px" icon="iconfont iconshaixuan2" @click="searchShows"></el-button>
          <dynamicTable :checkboxVal="checkboxVal" @alter="alterCheckbok" />
        </div>
      </div>
      <!-- 设备归属管理table -->
      <el-table stripe style="width: 100%" :data="affiliateTable" :key="key" border fit highlight-current-row ref="tableDataRef">
        <el-table-column v-if="colData[0].istrue" min-width="130" align="center" prop="username" label="归属"></el-table-column>
        <el-table-column v-if="colData[1].istrue" min-width="130" align="center" prop="batch" label="批次"></el-table-column>
        <el-table-column v-if="colData[2].istrue" min-width="130" align="center" prop="value" label="SN码">
          <template slot-scope="scope">
            <div class="flex flex_spa">
              <el-link :type="scope.row.is_lock ? 'primary' : 'danger'" @click="snInfoShow(scope.row.value,scope.row)">
                {{scope.row.value}}<i class="iconfont iconjiesuo1" style="margin-left:5px" v-if="!scope.row.is_lock"></i>
              </el-link>
            </div>
          </template>
        </el-table-column>
        <el-table-column v-if="colData[3].istrue" min-width="110" align="center" label="在线状态" width="100">
          <template slot-scope="scope">
            <div class="flex flex_cen felx_align">
              <div class="state flex flex_cen" :class="scope.row.is_online == 1 ? 'on_line' : 'off_line'">
                <span>{{scope.row.is_online == 1 ? '在线' : '离线'}}</span>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column v-if="colData[4].istrue" min-width="140" align="center" prop="update_time" label="最后一次修改的时间"></el-table-column>
      </el-table>
      <!-- 分页 -->
      <div class="paging">
        <el-pagination :current-page.sync="listQuery.startSize" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :page-sizes="[10, 50, 100, 200]"
          layout="total, sizes, prev, pager, next, jumper" :total="total" :page-size="listQuery.pageSize">
        </el-pagination>
      </div>
    </div>
    <!-- 设备转交 -->
    <el-dialog :title="editSubjects ? '设备转交' : '设备回收'" :visible.sync="loadFormVisible" @close="addFormclose" :close-on-click-modal="false" :close-on-press-escape="false" width="35%">
      <el-form :model="deliverForm" :rules="rules" ref="ruleForm">
        <el-form-item :label="editSubjects ? '转交类型' : '回收类型'" label-width="130px" prop="userType">
          <el-radio-group v-model="deliverForm.userType" @input="resetSelect">
            <el-radio :label="1">子账号</el-radio>
            <el-radio :label="2">家长</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="deliverForm.userType==1" label="变更用户" label-width="130px" prop="username" >
          <el-select v-model="deliverForm.username" placeholder="请选择变更用户" @change="snSelectChange" filterable>
            <el-option v-for="(item,index) in snParams" :key="index" :label="`${item.username}  (${item.title})`" :value="item.username"></el-option>
          </el-select>
        </el-form-item>
<!--        <el-form-item v-else label="变更用户" label-width="130px" prop="username">-->
<!--          <el-select v-model="deliverForm.username" placeholder="请选择变更用户" @change="snSelectChange" filterable>-->
<!--            <el-option v-for="(item,index) in clientParams" :key="index" :label="item.username" :value="item.username"></el-option>-->
<!--          </el-select>-->
<!--        </el-form-item>-->
        <el-form-item v-if="deliverForm.userType==1" :label="editSubjects ? '设备转交' : '设备回收'" label-width="130px" class="snElsx">
          <div>
            <el-input autocomplete="off" placeholder="请点击上传，上传xls或xlsx文件" v-model="fileName"></el-input>
            <el-tooltip :disabled="!snDisabled" class="item mrg-top" effect="dark" content="请先选择用户方可上传" placement="top-start">
              <upload-excel-component class="flex" :before-upload="beforeUpload" @submitXlsx="submitXlsx" :disabled="snDisabled" :loading="!videoFlag">
                <span>{{videoFlag ? '' : goodsData + '%'}}</span>
              </upload-excel-component>
            </el-tooltip>
            <div style="margin-left:125px;color:#666666;font-weight:600;font-size:12px">大批量数据需要时间,请耐心等待</div>
          </div>
        </el-form-item>
        <el-form-item v-else label="sn:" label-width="130px" prop="sn">
          <el-input v-model="deliverForm.sn" placeholder="请输入sn号码" clearable style="width: 200px"></el-input>
        </el-form-item>
        <div v-if="snShow">
          <el-form-item label="成功导入:" label-width="130px" style="margin-bottom:0">共{{ snData.succeed}}条</el-form-item>
          <el-form-item label="导入失败:" label-width="130px" style="margin-bottom:0"> 共{{ snData.sameData}}条
            {{ this.snData.same.length >= 1 ? `( 位于:第${this.snData.same.toString()}行 ), 只展示前10行` : ''}}
          </el-form-item>
          <el-form-item label="总条数:" label-width="130px" style="margin-bottom:0">共{{snData.all}}条</el-form-item>
          <el-form-item v-if="this.snData.same.length >= 1" label-width="130px" style="margin-bottom:0">导入失败请重新上传</el-form-item>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="loadFormVisible = false" size="mini" round>取 消</el-button>
        <el-button v-if="editSubjects" type="primary" @click="transferToClient" size="mini" round>确 定</el-button>
        <!-- 设备回收按钮 -->
        <el-button v-else type="primary" @click="transferToClient" size="mini" round>确 定</el-button>
      </div>
    </el-dialog>
    <!-- SN码导出 -->
    <el-dialog title="SN码导出" :visible.sync="exporFormVisible" :close-on-click-modal="false" :close-on-press-escape="false" width="35%" @close="exporFormclose">
      <el-form :model="exporForm">
        <el-form-item label="导出类型:" label-width="130px">
          <el-radio-group v-model="exporForm.type" @change="brandclassifySelect">
            <el-radio label="1">导出全部</el-radio>
            <el-radio label="2">按归属导出</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="选择归属:" label-width="130px">
          <el-select v-model="exporForm.username" placeholder="请选择归属" :disabled="exporDisabled">
            <el-option v-for="(item,index) in snParams" :key="index" :label="`${item.username}  (${item.title})`" :value="item.username"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="exporFormVisible = false" size="mini" round>取 消</el-button>
        <el-button type="primary" @click="getexportModelSn" size="mini" round>确 定</el-button>
      </div>
    </el-dialog>
    <!-- 模板操作图片弹窗 -->
    <div class="component" v-if="imgShow">
      <div class="mbImg"><img src="@/assets/images/snGs.png" alt=""></div>
      <div class="masking" @click="imgShow = false"></div>
    </div>

    <!-- 查看SN信息弹窗 -->
    <sn-dialog :online="is_online" :visible.sync="snInfo" width="40%" @close="snInclose" :modal-append-to-body='false' :close-on-click-modal="false" :close-on-press-escape="false">
      <websocket-sn :snData="sn" :online="is_online"></websocket-sn>
    </sn-dialog>
  </div>
</template>

<script>
import UploadExcelComponent from "@/components/UploadExcelSn/index.vue";
import dynamicTable from "@/components/DynamicTable";
import objectable from "@/utils/objectable.js";
import battery from "@/components/electric"
import {
  querySn, deviceGetParam, deviceTransfer, snTransferOrRecovery, getAscription, queryModelSn, exportModelSn, launchScreenshot, querySnScreens, deleteAll, refreshEquipParam,
  singleSnReset, singleSnRestart, forceStopApp, getEquip, getAppBySn
} from "@/api/equipment.js";
import snDialog from "@/components/snDialog"
import { uninstallPackage } from "@/api/supervise";//删除应用信息
import { mapState } from 'vuex'
import WebsocketSn from '../sn/components/websocketSn'
import sninfoDetails from '../sn/components/sninfoDetails'
import { queryUsernameBatch } from "@/api/appUpdate.js";
import {getClientUser} from "@/api/equipment";
export default {
  components: { UploadExcelComponent, dynamicTable, snDialog, battery, WebsocketSn, sninfoDetails },
  data() {
    return {
      checkboxVal: ["归属", "批次", "SN码", "在线状态", "最后一次修改的时间"],
      key: 1,
      colData: [], //动态控制table
      total: 0,
      select: "sn", //搜索条件
      searchTable: "",
      //归属table
      affiliateTable: [],
      loadFormVisible: false,
      //设备转交表单
      deliverForm: { file: {}, username: '', userType: 1, sn: '' },
      fileName: '',
      rules: {
        username: [{ required: true, message: "请选择变更用户", trigger: "blur" }],
        userType: [{ required: true, message: "请选择变更类型", trigger: "blur" }],
      },
      //设备回收按钮控制
      editSubjects: true,
      //归属列表
      snParams: [],
      //客户端用户列表
      clientParams: [],
      //控制上传按钮
      snDisabled: true,
      //导入显示
      snShow: false,
      //上传后显示的数据
      snData: { same: [], sameData: 0, fail: [], succeed: '', all: '' },
      listQuery: { startSize: 1, pageSize: 10, userId: localStorage.getItem("ID"), type: 0, sn: undefined, bId: undefined, username: undefined, is_online: undefined },
      //导出设备归属控制
      exporFormVisible: false,
      //导出表单
      exporForm: { type: '1', username: '' },
      //导出表单归属选择器控制
      exporDisabled: true,
      //批次模板控制
      imgShow: false,
      videoFlag: true,
      //sn设备信息控制
      snInfo: false,
      websock: null,
      timeout: 50 * 1000,//50秒一次心跳
      timeoutObj: null,//心跳心跳倒计时
      serverTimeoutObj: null,//心跳倒计时
      timeoutnum: null,//断开 重连倒计时
      lockReconnect: false,//是否真正建立连接
      is_online: 2,
      sn: undefined,
      searchShow: false,
      batchArray: [],
      detailsShow: false,
      studentStatus: {}
    };
  },
  computed: {
    ...mapState({//获取上传滚动条
      goodsData: state => state.user.progress
    })
  },
  created() {
    this.colData = objectable(this.checkboxVal, this.checkboxVal); //转为数组对象，好控制table
    this.getquerySn()
    this.getAscriptions()
    this.getClientUsers()
  },
  destroyed() {
    //离开路由之后断开websocket连接
    if (this.websock) {
      this.websock.close()
      this.close()
    }
  },
  methods: {
    sninfoClose() {
      this.detailsShow = false
      this.websock.close()
      this.close()
    },
    searchShows() {
      this.searchShow = !this.searchShow
    },
    infoChange(val) {
      this.listQuery.bId = undefined
      this.getqueryUsernameBatch(val)
    },
    //根据用户获取批次
    getqueryUsernameBatch(name) {
      queryUsernameBatch({ username: name }).then(res => {
        this.batchArray = res.data
      }).catch(err => {
        this.batchArray = []
      })
    },
    //复杂查询
    restParams() {
      this.listQuery = { startSize: 1, pageSize: 10, userId: localStorage.getItem("ID"), type: 1, value: undefined, admin_id: undefined, batch: undefined }
    },
    //点击sn查询设备信息
    snInfoShow(sn, item) {
      //解锁状态下，无法弹出设备信息窗口
      //if (type == 0) return this.$message.error('该设备已解锁')
      this.studentStatus = item
      this.infoSn = sn
      this.sn = sn
      this.initWebSocket()
      this.detailsShow = true
      //this.snInfo = true
    },
    //websocket
    initWebSocket() { //初始化weosocket
      const wsuri = process.env.VUE_APP_BASE_API == "https://name.uiuios.com/" ? "ws://39.108.116.195:2020" : "wss://www.jiaoguanyi.cn:2020"
      //const wsuri = "ws://127.0.0.1:8000";
      this.websock = new WebSocket(wsuri);
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    websocketonopen() { //连接建立之后执行send方法发送数据
      this.start();
      this.websock.send('sn:' + this.infoSn)
      console.log("socket连接成功", 'sn:' + this.infoSn)
    },
    websocketonerror() {//连接建立失败重连
      this.initWebSocket();
      console.log('连接建立失败重连')
    },
    websocketonmessage(e) { //数据接收
      const redata = JSON.parse(e.data);
      if (redata.code == 200 && redata.sn == this.infoSn) {
        this.is_online = redata.is_online
        //console.log("数据接收", redata)
      }
    },
    websocketsend(Data) {//数据发送 srwmy000
      this.websock.send(this.infoSn);
    },
    websocketclose(e) {  //关闭
      console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
    },
    reset() {//重置心跳
      var that = this;
      //清除时间
      clearTimeout(that.timeoutObj);
      clearTimeout(that.serverTimeoutObj);
      //重启心跳
      that.start();
    },
    close() {
      var that = this;
      //清除时间
      clearTimeout(that.timeoutObj);
      clearTimeout(that.serverTimeoutObj);
    },
    start() {//开启心跳
      var that = this;
      that.timeoutObj && clearTimeout(that.timeoutObj);
      that.serverTimeoutObj && clearTimeout(that.serverTimeoutObj);
      that.timeoutObj = setTimeout(function () {
        that.reset()
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (that.websock.readyState == 1) {   //如果连接正常
          that.websock.send('sn:' + that.infoSn);
        } else {//否则重连
          that.reconnect();
        }
        that.serverTimeoutObj = setTimeout(function () {
          //超时关闭
          that.websock.close();
        }, that.timeout);
      }, that.timeout)
    },
    reconnect() {//重新连接
      var that = this;
      if (that.lockReconnect) {
        return;
      };
      that.lockReconnect = true;
      //没连接上会一直重连，设置延迟避免请求过多
      that.timeoutnum && clearTimeout(that.timeoutnum);
      that.timeoutnum = setTimeout(function () {
        //新连接
        that.initWebSocket();
        that.lockReconnect = false;
      }, 5000);
    },
    //导出设备归属
    getexportModelSn() {
      let exporForm = JSON.parse(JSON.stringify(this.exporForm))
      exporForm.userId = localStorage.getItem("ID")
      this.exporDisabled ? delete exporForm.username : exporForm.username
      exportModelSn(exporForm).then(res => {
        window.open('https://' + res.data.url)
      })
    },
    //导出表单type选择
    brandclassifySelect(val) {
      this.exporDisabled = true
      switch (val) {
        case '2':
          this.exporDisabled = false
          break;
      }
    },
    //设备维护获取归属用户信息
    getAscriptions() {
      getAscription({ userId: localStorage.getItem("ID") }).then(res => {
        this.snParams = res.data
      })
    },
    //家长用户获取
    getClientUsers() {
      getClientUser({userId: localStorage.getItem("ID")}).then(res => {
        this.clientParams = res.data
      })
    },
    resetSelect(e) {
      this.deliverForm.username = ""
    },
    getquerySn() {
      queryModelSn(this.listQuery).then(res => {
        this.total = res.total
        this.affiliateTable = res.data
      }).catch(err => {
        this.affiliateTable = []
        this.total = 0
      })
    },
    submitXlsx() {
      var fd = new FormData()
      fd.append('file', this.deliverForm.file)
      fd.append('userId', localStorage.getItem("ID"))
      fd.append('last_ip', sessionStorage.getItem("Ip"))
      fd.append('type', this.editSubjects ? 1 : 2)
      fd.append('username', this.deliverForm.username)
      fd.append('userType', this.deliverForm.userType)
      this.videoFlag = false
      this.snDisabled = true
      snTransferOrRecovery(fd).then(res => {
        this.snShow = true
        this.snData.sameData = res.data[2].length
        this.snData.same = JSON.parse(JSON.stringify(res.data[2].splice(0, 10)))
        this.snData.succeed = res.data.excelSuccess
        this.snData.all = res.data.total
        this.$message.success('导入成功')
        this.videoFlag = true
        this.snDisabled = false
        this.getquerySn();
      }).catch(err => {
        this.snDisabled = false
        this.videoFlag = true
      })
    },
    transferToClient() {
      if (this.deliverForm.userType == 2) {
        snTransferOrRecovery({
          userId: localStorage.getItem("ID"),
          last_ip: sessionStorage.getItem("Ip"),
          type: this.editSubjects ? 1 : 2,
          username: this.deliverForm.username,
          sn: this.deliverForm.sn,
          userType: this.deliverForm.userType
        }).then(res => {
          this.$message.success("成功")
          this.loadFormVisible = false
        }).catch(err => {
          this.$message.error(err.message)
        })
      }else {
        this.loadFormVisible = false
      }
    },
    //SN码导入上传
    beforeUpload(file) {
      this.deliverForm.file = file
      this.fileName = file.name
    },
    snSelectChange(val) {
      if (!val) {
        this.snDisabled = true
      } else {
        this.snDisabled = false
      }
    },
    deviceGetParam() {
      let data = { userId: localStorage.getItem("ID") }
      deviceGetParam(data).then(res => {
        this.affiliation = res.data
      })
    },
    //搜索,1:sn码,2:归属,3:批次,4:系统固件版本号,5:设备信息版本号,6:教官壹版本号,7:在线
    idnameSearch() {
      if (!this.select) return this.$message.warning("请先选择查询条件");
      this.listQuery = Object.assign({}, this.$options.data().listQuery, { [this.select]: this.searchTable || undefined })
      this.getquerySn();
    },
    //设备回收
    equipment() {
      this.editSubjects = false
      this.loadFormVisible = true
      this.deviceGetParam()
    },
    getdeviceGetParam() {
      this.editSubjects = true
      this.loadFormVisible = true
    },
    //编辑添加表单关闭事件
    addFormclose() {
      this.$nextTick(() => {
        this.$refs.ruleForm.resetFields();
        this.deliverForm = { file: {}, username: '', userType: 1, sn: '' }
        this.fileName = ''
        this.snDisabled = true
        this.snShow = false
        this.videoFlag = true
      })
    },
    //批次创立更新导入模板
    handleDownload() {
      import("@/vendor/Export2Excel").then(excel => {
        const tHeader = ["SN码"];
        const filterVal = ["sn"];
        const list = [{ "sn": 'QNS2HIYS0003' }]
        const data = this.formatJson(filterVal, list);
        excel.export_json_to_excel({ header: tHeader, data, filename: 'SN码归属导入模板' });
      });
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map(v =>
        filterVal.map(j => {
          if (j === "timestamp") {
            return parseTime(v[j]);
          } else {
            return v[j];
          }
        })
      );
    },
    handleSizeChange(val) {
      this.listQuery.pageSize = val
      this.getquerySn();
    },
    handleCurrentChange(val) {
      this.listQuery.startSize = val
      this.getquerySn();
    },
    Refresh() {
      this.listQuery = { startSize: 1, pageSize: 10, userId: localStorage.getItem("ID"), type: 0, sn: undefined, bId: undefined, username: undefined, is_online: undefined }
      this.getquerySn()
    },
    exporFormclose() {
      this.exporForm = { type: '1', username: '' }
      this.exporDisabled = true
    },
    snInclose() {
      this.sn = undefined
      this.is_online = 2
      this.websock.close()//断开长链接
      this.close()
    },
    //下拉动态table子组件
    alterCheckbok(key, conte) {
      this.key = key;
      this.colData.filter(i => {
        if (conte.indexOf(i.title) != -1) {
          i.istrue = false;
          this.$nextTick(() => {
            this.$refs.tableDataRef.doLayout();
          });
        } else {
          i.istrue = true;
          this.$nextTick(() => {
            this.$refs.tableDataRef.doLayout();
          });
        }
      });
    }
  }
};
</script>

<style scoped>
.state {
  width: 60%;
  border-radius: 4px;
  background-image: none;
  background: #fff;
  border: 1px solid #dcdfe6;
}
/deep/ .el-collapse-item__header {
  background-color: #f9f9f9;
}
/deep/ .el-collapse-item__content {
  padding-bottom: 0;
}
</style>
